package com.smart.community.region.controller;

import java.util.List;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.smart.community.commons.annotation.ApiLog;
import com.smart.community.commons.enums.ApiLogOperationType;
import com.smart.community.commons.result.Result;
import com.smart.community.commons.utils.SecurityUtils;
import com.smart.community.region.dto.BatchUpdateHouseTypeDTO;
import com.smart.community.region.dto.HouseholdDTO;
import com.smart.community.region.dto.HouseholdQueryDTO;
import com.smart.community.region.dto.HouseholdUpdateDTO;
import com.smart.community.region.entity.Household;
import com.smart.community.region.service.IHouseholdService;
import com.smart.community.region.vo.HouseholdDeleteImpactVO;

import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;

/**
 * 房户管理控制器
 * 
 * @author Wu.Liang
 * @version 1.0.0
 * @since 2025-01-30
 */
@Slf4j
@RestController
@RequestMapping("/region/households")
@Tag(name = "房户管理", description = "房户管理相关接口")
public class HouseholdController {

    @Autowired
    private IHouseholdService householdService;

    // ==================== 基础CRUD接口 ====================

    /**
     * 分页查询房户列表
     * 
     * @param queryDTO 查询条件
     * @return 房户分页列表
     * @throws Exception 统一异常
     */
    @GetMapping
    @Operation(summary = "分页查询房户列表", description = "根据条件分页查询房户列表")
    public Result<IPage<Household>> getHouseholdPage(@Parameter(description = "查询条件") HouseholdQueryDTO queryDTO) throws Exception {
        log.info("分页查询房户列表，查询条件：{}", queryDTO);
        IPage<Household> result = householdService.getHouseholdPage(queryDTO);
        return Result.success(result);
    }

    /**
     * 获取房户详情
     * 
     * @param householdId 房户ID
     * @return 房户详情
     * @throws Exception 统一异常
     */
    @GetMapping("/{householdId}")
    @Operation(summary = "获取房户详情", description = "根据房户ID获取房户详细信息")
    public Result<Household> getHouseholdDetail(@Parameter(description = "房户ID") @PathVariable Long householdId) throws Exception {
        log.info("获取房户详情，房户ID：{}", householdId);
        Household household = householdService.getHouseholdDetail(householdId);
        if (household == null) {
            return Result.error("房户不存在");
        }
        return Result.success(household);
    }

    /**
     * 创建房户
     * 
     * @param householdDTO 房户信息
     * @return 创建结果
     * @throws Exception 统一异常
     */
    @ApiLog(logTitle = "创建房户", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.ADD)
    @PostMapping
    @Operation(summary = "创建房户", description = "创建新的房户")
    public Result<Boolean> createHousehold(@Parameter(description = "房户信息") @RequestBody @Valid HouseholdDTO householdDTO) throws Exception {
        log.info("创建房户，房户信息：{}", householdDTO);
        boolean result = householdService.createHousehold(householdDTO);
        return Result.success(result);
    }

    /**
     * 更新房户
     * 
     * @param householdId 房户ID
     * @param householdDTO 房户信息
     * @return 更新结果
     * @throws Exception 统一异常
     */
    @ApiLog(logTitle = "更新房户", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.UPDATE)
    @PutMapping("/{householdId}")
    @Operation(summary = "更新房户", description = "更新房户信息")
    public Result<Boolean> updateHousehold(@Parameter(description = "房户ID") @PathVariable Long householdId,
            @Parameter(description = "房户信息") @RequestBody @Valid HouseholdUpdateDTO householdDTO) throws Exception {
        log.info("更新房户，房户ID：{}，房户信息：{}", householdId, householdDTO);
        householdDTO.setId(householdId);
        boolean result = householdService.updateHousehold(householdDTO);
        return Result.success(result);
    }

    /**
     * 删除房户（带关联检查）
     * 
     * @param householdId 房户ID
     * @return 删除结果
     * @throws Exception 统一异常
     */
    @DeleteMapping("/{householdId}")
    @Operation(summary = "删除房户", description = "删除指定房户，会检查并处理所有关联数据")
    @SaCheckPermission("region:household:delete")
    @ApiLog(logTitle = "删除房户", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.DELETE)
    public Result<String> deleteHousehold(@Parameter(description = "房户ID") @PathVariable Long householdId) throws Exception {
        log.info("删除房户，房户ID：{}", householdId);
        Long currentUserId = SecurityUtils.getCurrentUserId();
        String result = householdService.deleteHouseholdWithRelations(householdId, currentUserId);
        return Result.success(result);
    }

    /**
     * 批量删除房户（带关联检查）
     * 
     * @param householdIds 房户ID列表
     * @return 删除结果
     * @throws Exception 统一异常
     */
    @DeleteMapping("/batch")
    @Operation(summary = "批量删除房户", description = "批量删除房户，会检查并处理所有关联数据")
    @SaCheckPermission("region:household:delete")
    @ApiLog(logTitle = "批量删除房户", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.DELETE)
    public Result<String> batchDeleteHouseholds(@Parameter(description = "房户ID列表") @RequestBody List<Long> householdIds) throws Exception {
        log.info("批量删除房户，房户ID列表：{}", householdIds);
        Long currentUserId = SecurityUtils.getCurrentUserId();
        String result = householdService.batchDeleteHouseholdsWithRelations(householdIds, currentUserId);
        return Result.success(result);
    }

    // ==================== 查询接口 ====================

    /**
     * 根据房户编码获取房户
     * 
     * @param householdCode 房户编码
     * @return 房户信息
     * @throws Exception 统一异常
     */
    @GetMapping("/code/{householdCode}")
    @Operation(summary = "根据房户编码获取房户", description = "根据房户编码获取房户信息")
    public Result<Household> getHouseholdByCode(@Parameter(description = "房户编码") @PathVariable String householdCode) throws Exception {
        log.info("根据房户编码获取房户，房户编码：{}", householdCode);
        Household household = householdService.getHouseholdByCode(householdCode);
        if (household == null) {
            return Result.error("房户不存在");
        }
        return Result.success(household);
    }

    /**
     * 根据单元ID获取房户列表
     * 
     * @param unitId 单元ID
     * @return 房户列表
     * @throws Exception 统一异常
     */
    @GetMapping("/unit/{unitId}")
    @Operation(summary = "根据单元ID获取房户列表", description = "获取指定单元下的所有房户")
    public Result<List<Household>> getHouseholdsByUnit(@Parameter(description = "单元ID") @PathVariable Long unitId) throws Exception {
        log.info("根据单元ID获取房户列表，单元ID：{}", unitId);
        List<Household> households = householdService.getHouseholdByUnitId(unitId);
        return Result.success(households);
    }

    // ==================== 状态管理接口 ====================

    /**
     * 更新房户状态
     * 
     * @param householdId 房户ID
     * @param status 状态：0-禁用，1-启用
     * @return 更新结果
     * @throws Exception 统一异常
     */
    @ApiLog(logTitle = "更新房户状态", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.UPDATE)
    @PutMapping("/{householdId}/status")
    @Operation(summary = "更新房户状态", description = "更新房户启用/禁用状态")
    public Result<Boolean> updateHouseholdStatus(@Parameter(description = "房户ID") @PathVariable Long householdId,
            @Parameter(description = "状态：0-禁用，1-启用") @RequestParam Integer status) throws Exception {
        log.info("更新房户状态，房户ID：{}，状态：{}", householdId, status);
        boolean result = householdService.updateHouseholdStatus(householdId, status);
        return Result.success(result);
    }

    /**
     * 批量更新房户状态
     * 
     * @param householdIds 房户ID列表
     * @param status 状态：0-禁用，1-启用
     * @return 更新结果
     * @throws Exception 统一异常
     */
    @ApiLog(logTitle = "批量更新房户状态", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.UPDATE)
    @PutMapping("/batch/status")
    @Operation(summary = "批量更新房户状态", description = "批量更新多个房户的状态")
    public Result<Boolean> batchUpdateHouseholdStatus(@Parameter(description = "房户ID列表") @RequestBody List<Long> householdIds,
            @Parameter(description = "状态：0-禁用，1-启用") @RequestParam Integer status) throws Exception {
        log.info("批量更新房户状态，房户ID列表：{}，状态：{}", householdIds, status);
        boolean result = householdService.batchUpdateHouseholdStatus(householdIds, status);
        return Result.success(result);
    }

    // ==================== 户型管理接口 ====================

    /**
     * 批量更新房户户型
     * 
     * @param dto 批量更新户型信息
     * @return 更新结果
     * @throws Exception 统一异常
     */
    @ApiLog(logTitle = "批量更新房户户型", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.UPDATE)
    @PutMapping("/batch/house-type")
    @Operation(summary = "批量更新房户户型", description = "批量更新多个房户的户型配置")
    public Result<Boolean> batchUpdateHouseType(@Parameter(description = "批量更新户型信息") @RequestBody @Valid BatchUpdateHouseTypeDTO dto) throws Exception {
        log.info("批量更新房户户型，房户ID列表：{}，户型ID：{}", dto.getHouseholdIds(), dto.getHouseTypeId());
        boolean result = householdService.batchUpdateHouseholdHouseType(dto.getHouseholdIds(), dto.getHouseTypeId());
        return Result.success(result);
    }

    // ==================== 验证接口 ====================

    /**
     * 检查房户编码唯一性
     * 
     * @param householdCode 房户编码
     * @param excludeHouseholdId 排除的房户ID
     * @return 是否唯一
     * @throws Exception 统一异常
     */
    @GetMapping("/check/code")
    @Operation(summary = "检查房户编码唯一性", description = "检查房户编码是否已存在")
    public Result<Boolean> checkHouseholdCodeUnique(@Parameter(description = "房户编码") @RequestParam String householdCode,
            @Parameter(description = "排除的房户ID") @RequestParam(required = false) Long excludeHouseholdId) throws Exception {
        log.info("检查房户编码唯一性，房户编码：{}，排除房户ID：{}", householdCode, excludeHouseholdId);
        boolean result = householdService.checkHouseholdCodeUnique(householdCode, excludeHouseholdId);
        return Result.success(result);
    }

    // ==================== 删除影响检查接口 ====================

    /**
     * 检查房户删除影响
     * 
     * @param householdId 房户ID
     * @return 删除影响分析
     * @throws Exception 统一异常
     */
    @GetMapping("/{householdId}/delete-impact")
    @Operation(summary = "检查房户删除影响", description = "分析删除房户会对哪些关联数据造成影响")
    @SaCheckPermission("region:household:view")
    @ApiLog(logTitle = "检查房户删除影响", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.QUERY)
    public Result<HouseholdDeleteImpactVO> checkDeleteImpact(@Parameter(description = "房户ID") @PathVariable Long householdId) throws Exception {
        log.info("检查房户删除影响，房户ID：{}", householdId);
        HouseholdDeleteImpactVO impact = householdService.checkDeleteImpact(householdId);
        return Result.success(impact);
    }

    // ==================== 统计接口 ====================

    /**
     * 获取房户统计信息
     * 
     * @param householdId 房户ID
     * @return 统计信息
     * @throws Exception 统一异常
     */
    @GetMapping("/{householdId}/stats")
    @Operation(summary = "获取房户统计信息", description = "获取指定房户的统计信息")
    public Result<Object> getHouseholdStats(@Parameter(description = "房户ID") @PathVariable Long householdId) throws Exception {
        log.info("获取房户统计信息，房户ID：{}", householdId);
        Object result = householdService.getHouseholdStats(householdId);
        return Result.success(result);
    }

    // ==================== 房户详情Tab页接口 ====================

    /**
     * 获取房户业主列表
     * 
     * @param householdId 房户ID
     * @param current 当前页
     * @param size 每页大小
     * @return 业主列表
     * @throws Exception 统一异常
     */
    @GetMapping("/{householdId}/owners")
    @Operation(summary = "获取房户业主列表", description = "根据房户ID获取关联的业主列表")
    public Result<IPage<Object>> getHouseholdOwners(
            @Parameter(description = "房户ID") @PathVariable Long householdId,
            @Parameter(description = "当前页") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Integer size) throws Exception {
        log.info("获取房户业主列表，房户ID：{}，当前页：{}，每页大小：{}", householdId, current, size);
        IPage<Object> result = householdService.getHouseholdOwners(householdId, current, size);
        return Result.success(result);
    }

    /**
     * 获取房户家庭成员列表
     * 
     * @param householdId 房户ID
     * @param current 当前页
     * @param size 每页大小
     * @return 家庭成员列表
     * @throws Exception 统一异常
     */
    @GetMapping("/{householdId}/family-members")
    @Operation(summary = "获取房户家庭成员列表", description = "根据房户ID获取家庭成员列表（residentType=1或2）")
    public Result<IPage<Object>> getHouseholdFamilyMembers(
            @Parameter(description = "房户ID") @PathVariable Long householdId,
            @Parameter(description = "当前页") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Integer size) throws Exception {
        log.info("获取房户家庭成员列表，房户ID：{}，当前页：{}，每页大小：{}", householdId, current, size);
        IPage<Object> result = householdService.getHouseholdFamilyMembers(householdId, current, size);
        return Result.success(result);
    }

    /**
     * 获取房户租客列表
     * 
     * @param householdId 房户ID
     * @param current 当前页
     * @param size 每页大小
     * @return 租客列表
     * @throws Exception 统一异常
     */
    @GetMapping("/{householdId}/tenants")
    @Operation(summary = "获取房户租客列表", description = "根据房户ID获取租客列表（residentType=3或4）")
    public Result<IPage<Object>> getHouseholdTenants(
            @Parameter(description = "房户ID") @PathVariable Long householdId,
            @Parameter(description = "当前页") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") Integer size) throws Exception {
        log.info("获取房户租客列表，房户ID：{}，当前页：{}，每页大小：{}", householdId, current, size);
        IPage<Object> result = householdService.getHouseholdTenants(householdId, current, size);
        return Result.success(result);
    }

    // ==================== 缓存管理接口 ====================

    /**
     * 清除房户缓存
     * 
     * @param householdId 房户ID
     * @return 清除结果
     * @throws Exception 统一异常
     */
    @ApiLog(logTitle = "清除房户缓存", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.DELETE)
    @DeleteMapping("/cache/{householdId}")
    @Operation(summary = "清除房户缓存", description = "清除指定房户的缓存")
    public Result<Boolean> clearHouseholdCache(@Parameter(description = "房户ID") @PathVariable Long householdId) throws Exception {
        log.info("清除房户缓存，房户ID：{}", householdId);
        householdService.clearHouseholdCache(householdId);
        return Result.success(true);
    }

    /**
     * 清除所有房户缓存
     * 
     * @return 清除结果
     * @throws Exception 统一异常
     */
    @ApiLog(logTitle = "清除所有房户缓存", logType = 2, moduleName = "区域管理", operationType = ApiLogOperationType.DELETE)
    @DeleteMapping("/cache/all")
    @Operation(summary = "清除所有房户缓存", description = "清除所有房户相关的缓存")
    public Result<Boolean> clearAllHouseholdCache() throws Exception {
        log.info("清除所有房户缓存");
        householdService.clearAllHouseholdCache();
        return Result.success(true);
    }
}